package cn.iocoder.yudao.module.erp.controller.admin.finance.bankstatementitem;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.finance.bankstatementitem.vo.BankStatementItemPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.finance.bankstatementitem.vo.BankStatementItemRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.finance.bankstatementitem.vo.BankStatementItemSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dp.DpDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.bankstatementitem.BankStatementItemDO;
import cn.iocoder.yudao.module.erp.service.dp.DpService;
import cn.iocoder.yudao.module.erp.service.finance.bankstatementitem.BankStatementItemService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 银行流水明细")
@RestController
@RequestMapping("/erp/bank-statement-item")
@Validated
public class BankStatementItemController {

    @Resource
    private BankStatementItemService bankStatementItemService;
    @Resource
    private DpService dpService;

    @PostMapping("/create")
    @Operation(summary = "创建银行流水明细")
    // @PreAuthorize("@ss.hasPermission('erp:bank-statement-item:create')")
    public CommonResult<Long> createBankStatementItem(@Valid @RequestBody BankStatementItemSaveReqVO createReqVO) {
        return success(bankStatementItemService.createBankStatementItem(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新银行流水明细")
    // @PreAuthorize("@ss.hasPermission('erp:bank-statement-item:update')")
    public CommonResult<Boolean> updateBankStatementItem(@Valid @RequestBody BankStatementItemSaveReqVO updateReqVO) {
        bankStatementItemService.updateBankStatementItem(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除银行流水明细")
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('erp:bank-statement-item:delete')")
    public CommonResult<Boolean> deleteBankStatementItem(@RequestParam("id") Long id) {
        bankStatementItemService.deleteBankStatementItem(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得银行流水明细")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    // @PreAuthorize("@ss.hasPermission('erp:bank-statement-item:query')")
    public CommonResult<BankStatementItemRespVO> getBankStatementItem(@RequestParam("id") Long id) {
        BankStatementItemDO bankStatementItem = bankStatementItemService.getBankStatementItem(id);
        return success(BeanUtils.toBean(bankStatementItem, BankStatementItemRespVO.class));
    }

    @GetMapping("/getNoByShipper")
    @Operation(summary = "模糊查询发货人")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    // @PreAuthorize("@ss.hasPermission('erp:bank-statement-item:query')")
    public CommonResult<List<DpDO>> getNoByShipper(@RequestParam(value = "shipper", required = false) String shipper) {
        List<DpDO> noByShipper = dpService.getNoByShipper(shipper);
        return success(noByShipper);
    }


    @GetMapping("/page")
    @Operation(summary = "获得银行流水明细分页")
    // @PreAuthorize("@ss.hasPermission('erp:bank-statement-item:query')")
    public CommonResult<PageResult<BankStatementItemRespVO>> getBankStatementItemPage(@Valid BankStatementItemPageReqVO pageReqVO) {
        PageResult<BankStatementItemDO> pageResult = bankStatementItemService.getBankStatementItemPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, BankStatementItemRespVO.class));
    }

    @GetMapping("/getBankItemAmountTotal")
    @Operation(summary = "银行流水明细金额统计")
    // @PreAuthorize("@ss.hasPermission('erp:bank-statement-item:query')")
    public CommonResult<BankStatementItemDO> getBankItemAmountTotal(@Valid BankStatementItemPageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        BankStatementItemDO bankStatementItemDO = bankStatementItemService.getBankItemAmountTotal(pageReqVO);
        return success(bankStatementItemDO);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出银行流水明细 Excel")
    // @PreAuthorize("@ss.hasPermission('erp:bank-statement-item:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportBankStatementItemExcel(@Valid BankStatementItemPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<BankStatementItemDO> list = bankStatementItemService.getBankStatementItemPage(pageReqVO).getList();
        // 对数据进行字段处理
        List<BankStatementItemRespVO> processedList = list.stream().map(bankItemDO -> {
            BankStatementItemRespVO respVO = BeanUtils.toBean(bankItemDO, BankStatementItemRespVO.class);
            // 格式化创建时间
            String recordDate = bankItemDO.getRecordDate();
            if (recordDate != null) {
                LocalDate recordDateFormatted = LocalDate.parse(recordDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                respVO.setRecordDateFormatted(recordDateFormatted.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            }
            return respVO;
        }).collect(Collectors.toList());

        // 计算字段总和
        double incomeAmountSum = list.stream()
                .mapToDouble(BankStatementItemDO::getIncomeAmount) // 转换为 DoubleStream
                .sum(); // 计算总和
        double payAmountSum = list.stream()
                .mapToDouble(BankStatementItemDO::getPayAmount)
                .sum();
        Double balanceSum = 0.0;
        if (processedList!=null && processedList.size()>0) {
            balanceSum = processedList.get(0).getBalance();
        }
        BankStatementItemRespVO respVO = new BankStatementItemRespVO();
        respVO.setCardId("合计");
        respVO.setIncomeAmount(incomeAmountSum);
        respVO.setPayAmount(payAmountSum);
        respVO.setBalance(balanceSum);
        processedList.add(respVO);
        // 导出 Excel
        ExcelUtils.write(response, "银行流水明细.xls", "数据", BankStatementItemRespVO.class, processedList);
    }

}